package edu.vub.at.kryo;

import java.util.ArrayList;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.ReferenceResolver;
import com.esotericsoftware.kryo.util.IdentityObjectIntMap;
import com.esotericsoftware.kryo.util.Util;
import com.esotericsoftware.minlog.Log;

public class ExtendedMapReferenceResolver implements ReferenceResolver {
	protected Kryo kryo;
	protected final IdentityObjectIntMap writtenObjects = new IdentityObjectIntMap();
	protected final ArrayList readObjects = new ArrayList();

	public void setKryo (Kryo kryo) {
		this.kryo = kryo;
	}

	public int addWrittenObject (Object object) {
		//Log.warn("add "  + object.getClass().toString());

		int id = writtenObjects.size;
//		if (object instanceof NativeATObject) {
//			Object newValue;
//			try {
//				newValue = ((NativeATObject) object).writeReplace();
//				object = newValue;
//			} catch (ObjectStreamException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//		}
		
		writtenObjects.put(object, id);
		return id;
	}

	public int getWrittenId (Object object) {
		return writtenObjects.get(object, -1);
	}

	public int nextReadId (Class type) {
		int id = readObjects.size();
		readObjects.add(null);
		return id;
	}

	public void setReadObject (int id, Object object) {
		readObjects.set(id, object);
	}

	public Object getReadObject (Class type, int id) {
		Log.warn(type.toString());
		
		Object readObject = readObjects.get(id);
//		if (readObject != null && readObject instanceof NativeATObject) {
//			try {
//				readObject = ((NativeATObject) readObject).readResolve();
//			} catch (ObjectStreamException e) {
//				e.printStackTrace();
//			}
//		}
		return readObject;
	}

	public void reset () {
		readObjects.clear();
		writtenObjects.clear();
	}

	/** Returns false for all primitive wrappers. */
	public boolean useReferences (Class type) {
		return !Util.isWrapperClass(type);
	}
}